<template>
  <div class="prediction-container">
    <!-- 页面标题 -->
    <div class="page-header">
      <h2>ML.net 智能预测系统</h2>
      <p>基于历史数据预测出库量、入库量和商品量</p>
    </div>

    <!-- 预测参数设置 -->
    <el-card class="prediction-card">
      <template #header>
        <div class="card-header">
          <span>预测参数设置</span>
        </div>
      </template>
      
      <el-form :model="predictionForm" label-width="120px" class="prediction-form">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="预测时间范围">
              <el-select v-model="predictionForm.timeRange" placeholder="请选择预测时间范围">
                <el-option label="未来7天" value="7"></el-option>
                <el-option label="未来15天" value="15"></el-option>
                <el-option label="未来30天" value="30"></el-option>
                <el-option label="未来90天" value="90"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="商品类型">
              <el-select v-model="predictionForm.goodsType" placeholder="请选择商品类型" multiple>
                <el-option
                  v-for="item in goodsTypeList"
                  :key="item.goodstypecoding"
                  :value="item.goodstypecoding"
                  :label="item.wGoodstypename"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="预测模型">
              <el-select v-model="predictionForm.modelType" placeholder="请选择预测模型">
                <el-option label="线性回归" value="linear"></el-option>
                <el-option label="随机森林" value="randomForest"></el-option>
                <el-option label="神经网络" value="neuralNetwork"></el-option>
                <el-option label="时间序列" value="timeSeries"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="历史数据范围">
              <el-date-picker
                v-model="predictionForm.historyRange"
                type="daterange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                format="YYYY-MM-DD"
                value-format="YYYY-MM-DD"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="置信度阈值">
              <el-slider
                v-model="predictionForm.confidenceThreshold"
                :min="0.5"
                :max="0.95"
                :step="0.05"
                show-input
                input-size="small"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="季节性考虑">
              <el-switch
                v-model="predictionForm.considerSeasonality"
                active-text="是"
                inactive-text="否"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="24">
            <el-form-item>
              <el-button type="primary" @click="startPrediction" :loading="loading">
                <el-icon><DataAnalysis /></el-icon>
                开始预测
              </el-button>
              <el-button @click="resetForm">重置参数</el-button>
              <el-button type="success" @click="exportResults" :disabled="!hasResults">
                导出结果
              </el-button>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </el-card>

    <!-- 预测结果展示 -->
    <div v-if="hasResults" class="results-section">
      <!-- 预测概览 -->
      <el-card class="overview-card">
        <template #header>
          <div class="card-header">
            <span>预测概览</span>
            <el-tag type="success">预测完成</el-tag>
          </div>
        </template>
        
        <el-row :gutter="20">
          <el-col :span="8">
            <div class="metric-card">
              <div class="metric-title">预测出库量</div>
              <div class="metric-value">{{ predictionResults.totalOutbound }}</div>
              <div class="metric-unit">件</div>
              <div class="metric-trend" :class="predictionResults.outboundTrend > 0 ? 'up' : 'down'">
                <el-icon><ArrowUp v-if="predictionResults.outboundTrend > 0" /><ArrowDown v-else /></el-icon>
                {{ Math.abs(predictionResults.outboundTrend) }}%
              </div>
            </div>
          </el-col>
          <el-col :span="8">
            <div class="metric-card">
              <div class="metric-title">预测入库量</div>
              <div class="metric-value">{{ predictionResults.totalInbound }}</div>
              <div class="metric-unit">件</div>
              <div class="metric-trend" :class="predictionResults.inboundTrend > 0 ? 'up' : 'down'">
                <el-icon><ArrowUp v-if="predictionResults.inboundTrend > 0" /><ArrowDown v-else /></el-icon>
                {{ Math.abs(predictionResults.inboundTrend) }}%
              </div>
            </div>
          </el-col>
          <el-col :span="8">
            <div class="metric-card">
              <div class="metric-title">预测商品量</div>
              <div class="metric-value">{{ predictionResults.totalGoods }}</div>
              <div class="metric-unit">件</div>
              <div class="metric-trend" :class="predictionResults.goodsTrend > 0 ? 'up' : 'down'">
                <el-icon><ArrowUp v-if="predictionResults.goodsTrend > 0" /><ArrowDown v-else /></el-icon>
                {{ Math.abs(predictionResults.goodsTrend) }}%
              </div>
            </div>
          </el-col>
        </el-row>
      </el-card>

      <!-- 详细预测图表 -->
      <el-card class="chart-card">
        <template #header>
          <div class="card-header">
            <span>详细预测趋势</span>
            <el-radio-group v-model="selectedChart" size="small">
              <el-radio-button label="outbound">出库量</el-radio-button>
              <el-radio-button label="inbound">入库量</el-radio-button>
              <el-radio-button label="goods">商品量</el-radio-button>
            </el-radio-group>
          </div>
        </template>
        
        <div class="chart-container">
          <div ref="chartRef" style="width: 100%; height: 400px;"></div>
        </div>
      </el-card>

      <!-- 预测详情表格 -->
      <el-card class="table-card">
        <template #header>
          <div class="card-header">
            <span>预测详情</span>
            <el-button type="primary" size="small" @click="refreshTable">刷新</el-button>
          </div>
        </template>
        
        <el-table :data="predictionResults.details" style="width: 100%" border>
          <el-table-column prop="date" label="日期" width="120" />
          <el-table-column prop="outbound" label="预测出库量" width="120">
            <template #default="scope">
              <span class="prediction-value">{{ scope.row.outbound }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="inbound" label="预测入库量" width="120">
            <template #default="scope">
              <span class="prediction-value">{{ scope.row.inbound }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="goods" label="预测商品量" width="120">
            <template #default="scope">
              <span class="prediction-value">{{ scope.row.goods }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="confidence" label="置信度" width="100">
            <template #default="scope">
              <el-progress 
                :percentage="scope.row.confidence * 100" 
                :color="getConfidenceColor(scope.row.confidence)"
                :show-text="false"
              />
              <span class="confidence-text">{{ (scope.row.confidence * 100).toFixed(1) }}%</span>
            </template>
          </el-table-column>
          <el-table-column prop="modelAccuracy" label="模型准确度" width="120">
            <template #default="scope">
              <el-tag :type="getAccuracyType(scope.row.modelAccuracy)">
                {{ (scope.row.modelAccuracy * 100).toFixed(1) }}%
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="notes" label="备注" />
        </el-table>
      </el-card>

      <!-- 模型评估 -->
      <el-card class="evaluation-card">
        <template #header>
          <div class="card-header">
            <span>模型评估</span>
          </div>
        </template>
        
        <el-row :gutter="20">
          <el-col :span="6">
            <div class="evaluation-item">
              <div class="evaluation-label">R² 决定系数</div>
              <div class="evaluation-value">{{ (predictionResults.modelMetrics.r2 * 100).toFixed(2) }}%</div>
            </div>
          </el-col>
          <el-col :span="6">
            <div class="evaluation-item">
              <div class="evaluation-label">平均绝对误差</div>
              <div class="evaluation-value">{{ predictionResults.modelMetrics.mae.toFixed(2) }}</div>
            </div>
          </el-col>
          <el-col :span="6">
            <div class="evaluation-item">
              <div class="evaluation-label">均方根误差</div>
              <div class="evaluation-value">{{ predictionResults.modelMetrics.rmse.toFixed(2) }}</div>
            </div>
          </el-col>
          <el-col :span="6">
            <div class="evaluation-item">
              <div class="evaluation-label">训练时间</div>
              <div class="evaluation-value">{{ predictionResults.modelMetrics.trainingTime }}s</div>
            </div>
          </el-col>
        </el-row>
      </el-card>
    </div>

    <!-- 加载状态 -->
    <div v-if="loading" class="loading-overlay">
      <el-card class="loading-card">
        <div class="loading-content">
          <el-icon class="loading-icon"><Loading /></el-icon>
          <div class="loading-text">正在使用ML.net进行智能预测...</div>
          <div class="loading-progress">
            <el-progress :percentage="loadingProgress" :show-text="false" />
            <div class="progress-text">{{ loadingProgress }}%</div>
          </div>
        </div>
      </el-card>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { DataAnalysis, ArrowUp, ArrowDown, Loading } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
import { mlPredict, getGoodsTypes, type PredictionParams, type PredictionResult, type PredictionDetail } from '@/api/prediction'
import { generateMockPredictionData, adjustPredictionByModel, generateGoodsTypes } from '@/utils/mockPredictionData'

// 响应式数据
const loading = ref(false)
const loadingProgress = ref(0)
const hasResults = ref(false)
const selectedChart = ref('outbound')
const chartRef = ref<HTMLElement | null>(null)
let chartInstance: echarts.ECharts | null = null

// 表单数据
const predictionForm = reactive({
  timeRange: '30',
  goodsType: [],
  modelType: 'randomForest',
  historyRange: [],
  confidenceThreshold: 0.8,
  considerSeasonality: true
})

// 商品类型列表
interface GoodsType {
  goodstypecoding: string
  wGoodstypename: string
}

const goodsTypeList = ref<GoodsType[]>([{
  goodstypecoding: "",
  wGoodstypename: ""
}])

// 加载商品类型列表
const loadGoodsTypes = async () => {
  try {
    const response = await getGoodsTypes()
    if (response.data.success) {
      goodsTypeList.value = response.data.data as GoodsType[]
    }
  } catch (error) {
    console.error('加载商品类型失败:', error)
    // 使用模拟数据
    goodsTypeList.value = generateGoodsTypes() as GoodsType[]
  }
}

// 预测结果
const predictionResults = reactive<PredictionResult>({
  totalOutbound: 0,
  totalInbound: 0,
  totalGoods: 0,
  outboundTrend: 0,
  inboundTrend: 0,
  goodsTrend: 0,
  details: [],
  modelMetrics: {
    r2: 0,
    mae: 0,
    rmse: 0,
    trainingTime: 0
  }
})

// 开始预测
const startPrediction = async () => {
  if (!predictionForm.timeRange || !predictionForm.modelType) {
    ElMessage.warning('请完善预测参数')
    return
  }

  loading.value = true
  loadingProgress.value = 0
  
  try {
    // 模拟进度更新
    const progressInterval = setInterval(() => {
      if (loadingProgress.value < 90) {
        loadingProgress.value += Math.random() * 10
      }
    }, 500)

         // 调用后端ML.net预测接口
     const params: PredictionParams = {
       timeRange: parseInt(predictionForm.timeRange),
       goodsTypes: predictionForm.goodsType,
       modelType: predictionForm.modelType,
       historyRange: predictionForm.historyRange,
       confidenceThreshold: predictionForm.confidenceThreshold,
       considerSeasonality: predictionForm.considerSeasonality
     }
     
     let response
     try {
       response = await mlPredict(params)
     } catch (error) {
       console.log('使用模拟数据进行演示')
       // 如果后端接口不可用，使用模拟数据
       const mockData = generateMockPredictionData(parseInt(predictionForm.timeRange))
       const adjustedData = adjustPredictionByModel(mockData, predictionForm.modelType)
       response = {
         data: {
           success: true,
           data: adjustedData
         }
       }
     }

    clearInterval(progressInterval)
    loadingProgress.value = 100

    // 处理预测结果
    if (response.data.success) {
      Object.assign(predictionResults, response.data.data)
      hasResults.value = true
      
      await nextTick()
      initChart()
      
      ElMessage.success('预测完成！')
    } else {
      ElMessage.error(response.data.message || '预测失败')
    }
  } catch (error) {
    console.error('预测失败:', error)
    ElMessage.error('预测过程中发生错误，请重试')
  } finally {
    loading.value = false
    loadingProgress.value = 0
  }
}

// 初始化图表
const initChart = () => {
  if (!chartRef.value) return

  chartInstance = echarts.init(chartRef.value)
  
  const option = {
    title: {
      text: '预测趋势图',
      left: 'center'
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross'
      }
    },
    legend: {
      data: ['历史数据', '预测数据'],
      top: 30
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: predictionResults.details.map(item => item.date)
    },
    yAxis: {
      type: 'value'
    },
    series: [
      {
        name: '历史数据',
        type: 'line',
        data: predictionResults.details.map(item => item.historicalValue || null),
        itemStyle: {
          color: '#409EFF'
        }
      },
      {
        name: '预测数据',
        type: 'line',
        data: predictionResults.details.map(item => {
          switch (selectedChart.value) {
            case 'outbound': return item.outbound
            case 'inbound': return item.inbound
            case 'goods': return item.goods
            default: return item.outbound
          }
        }),
        itemStyle: {
          color: '#67C23A'
        },
        lineStyle: {
          type: 'dashed'
        }
      }
    ]
  }
  
  chartInstance.setOption(option)
}

// 重置表单
const resetForm = () => {
  Object.assign(predictionForm, {
    timeRange: '30',
    goodsType: [],
    modelType: 'randomForest',
    historyRange: [],
    confidenceThreshold: 0.8,
    considerSeasonality: true
  })
  hasResults.value = false
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
}

// 导出结果
const exportResults = () => {
  ElMessage.success('预测结果已导出')
}

// 刷新表格
const refreshTable = () => {
  ElMessage.success('表格已刷新')
}

// 获取置信度颜色
const getConfidenceColor = (confidence: number) => {
  if (confidence >= 0.8) return '#67C23A'
  if (confidence >= 0.6) return '#E6A23C'
  return '#F56C6C'
}

// 获取准确度类型
const getAccuracyType = (accuracy: number) => {
  if (accuracy >= 0.8) return 'success'
  if (accuracy >= 0.6) return 'warning'
  return 'danger'
}

// 监听图表类型变化
const watchSelectedChart = () => {
  if (chartInstance && hasResults.value) {
    initChart()
  }
}

// 组件挂载
onMounted(() => {
  // 获取商品类型列表
  loadGoodsTypes()
})

// 监听器
import { watch } from 'vue'
watch(selectedChart, watchSelectedChart)
</script>

<style scoped>
.prediction-container {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;
}

.page-header {
  text-align: center;
  margin-bottom: 30px;
}

.page-header h2 {
  color: #303133;
  margin-bottom: 10px;
}

.page-header p {
  color: #909399;
  font-size: 14px;
}

.prediction-card {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.prediction-form {
  margin-top: 20px;
}

.results-section {
  margin-top: 20px;
}

.overview-card {
  margin-bottom: 20px;
}

.metric-card {
  text-align: center;
  padding: 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 8px;
  color: white;
}

.metric-title {
  font-size: 14px;
  margin-bottom: 10px;
  opacity: 0.9;
}

.metric-value {
  font-size: 32px;
  font-weight: bold;
  margin-bottom: 5px;
}

.metric-unit {
  font-size: 12px;
  opacity: 0.8;
  margin-bottom: 10px;
}

.metric-trend {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
}

.metric-trend.up {
  color: #67C23A;
}

.metric-trend.down {
  color: #F56C6C;
}

.chart-card {
  margin-bottom: 20px;
}

.chart-container {
  padding: 20px 0;
}

.table-card {
  margin-bottom: 20px;
}

.prediction-value {
  font-weight: bold;
  color: #409EFF;
}

.confidence-text {
  margin-left: 10px;
  font-size: 12px;
  color: #909399;
}

.evaluation-card {
  margin-bottom: 20px;
}

.evaluation-item {
  text-align: center;
  padding: 15px;
  background-color: #f8f9fa;
  border-radius: 6px;
}

.evaluation-label {
  font-size: 12px;
  color: #909399;
  margin-bottom: 5px;
}

.evaluation-value {
  font-size: 18px;
  font-weight: bold;
  color: #303133;
}

.loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}

.loading-card {
  width: 400px;
}

.loading-content {
  text-align: center;
  padding: 30px;
}

.loading-icon {
  font-size: 48px;
  color: #409EFF;
  margin-bottom: 20px;
  animation: rotate 2s linear infinite;
}

.loading-text {
  font-size: 16px;
  color: #303133;
  margin-bottom: 20px;
}

.loading-progress {
  display: flex;
  align-items: center;
  gap: 10px;
}

.progress-text {
  font-size: 14px;
  color: #909399;
  min-width: 40px;
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .prediction-container {
    padding: 10px;
  }
  
  .metric-card {
    margin-bottom: 15px;
  }
  
  .evaluation-item {
    margin-bottom: 15px;
  }
}
</style> 